package main

import "fmt"

/*
Go 数组的长度不可改变，在特定场景中这样的集合就不太适用，Go 中提供了一种灵活，功能强悍的内置类型切片("动态数组")，与数组相比切片的长度是不固定的，可以追加元素，在追加时可能使切片的容量增大。

切片不需要说明长度。
或使用 make() 函数来创建切片:
var slice1 []type = make([]type, len)
也可以简写为
slice1 := make([]type, len)

切片本身就是一个动态数组（类似于python中的list和java中的list）



这个len就是初始的长度

切片也可以对于已有数组切分出一部分（类似于python）
s := arr[startIndex:endIndex]
将 arr 中从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片。

s := arr[startIndex:]
默认 endIndex 时将表示一直到arr的最后一个元素。

s := arr[:endIndex]
默认 startIndex 时将表示从 arr 的第一个元素开始。

s1 := s[startIndex:endIndex]

s :=make([]int,len,cap)
*/
func main() {
	/*
		切片是可索引的，并且可以由 len() 方法获取长度。

		切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。
	*/
	/*
		1. 切片声明
	*/
	var numbers = make([]int, 3, 5)

	printSlice(numbers) //len=3 cap=5 slice=[0 0 0]

	/*
		2. 空切片
	*/
	var numbers2 []int

	printSlice(numbers2)

	if numbers2 == nil {
		fmt.Printf("切片是空的")
	}

	/*
		3. 切片的截取
	*/
	/* 创建切片 */
	numbers3 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
	printSlice(numbers3)

	/* 打印原始切片 */
	fmt.Println("numbers ==", numbers3)

	/* 打印子切片从索引1(包含) 到索引4(不包含)*/
	fmt.Println("numbers[1:4] ==", numbers3[1:4])

	/* 默认下限为 0*/
	fmt.Println("numbers[:3] ==", numbers3[:3])

	/* 默认上限为 len(s)*/
	fmt.Println("numbers[4:] ==", numbers3[4:])

	numbers4 := make([]int, 0, 5)
	printSlice(numbers4) //len=0 cap=5 slice=[]

	/* 打印子切片从索引  0(包含) 到索引 2(不包含) */
	numbers5 := numbers3[:2]
	printSlice(numbers5) //len=2 cap=9 slice=[0 1]

	/* 打印子切片从索引 2(包含) 到索引 5(不包含) */
	numbers6 := numbers3[2:5]
	printSlice(numbers6) //len=3 cap=7 slice=[2 3 4]

	/*
		4. append()和copy()函数
		append是往切片内部增加元素
		copy()是把某一个切片的内容拷贝到另一个切片中，类似于java中的System.arraycopy()
	*/
	var numbers7 []int
	printSlice(numbers7) //len=0 cap=0 slice=[]

	/* 允许追加空切片 */
	numbers7 = append(numbers7, 0) //len=1 cap=1 slice=[0]
	printSlice(numbers7)

	/* 向切片添加一个元素 */
	numbers7 = append(numbers7, 1) //len=2 cap=2 slice=[0 1]
	printSlice(numbers7)

	/* 同时添加多个元素 */
	numbers7 = append(numbers7, 2, 3, 4)
	printSlice(numbers7) //len=5 cap=6 slice=[0 1 2 3 4]

	/* 创建切片 numbers1 是之前切片的两倍容量*/
	numbers8 := make([]int, len(numbers7), (cap(numbers7))*2)

	/* 拷贝 numbers 的内容到 numbers1 */
	copy(numbers8, numbers7)
	printSlice(numbers8) //len=5 cap=12 slice=[0 1 2 3 4]

}

func printSlice(x []int) {
	fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
